package com.yeskery.nut.scan.bean;

import com.yeskery.nut.bean.BeanPostProcessor;
import com.yeskery.nut.bean.BeanRegister;
import com.yeskery.nut.core.Order;
import com.yeskery.nut.scan.AnnotationHandler;
import com.yeskery.nut.scan.BeanAnnotationScanMetadata;
import com.yeskery.nut.util.BeanUtils;

import java.util.Arrays;
import java.util.Collection;

/**
 * 基于注解的Component扫描器
 * @author sprout
 * 2022-06-21 11:35
 */
public class AnnotationComponentHandler implements AnnotationHandler {

    /** bean注册器 */
    private final BeanRegister beanRegister;

    /**
     * 构建基于注解的Component扫描器
     * @param beanRegister Bean注册接口
     */
    public AnnotationComponentHandler(BeanRegister beanRegister) {
        this.beanRegister = beanRegister;
    }

    @Override
    public void handle(Collection<Class<?>> beanClassCollection, Collection<BeanAnnotationScanMetadata> beanMetadataCollection) {
        initializeBeanPostProcessor(beanMetadataCollection);
        for (Class<?> beanClass : beanClassCollection) {
            if (!beanRegister.containBean(beanClass)) {
                beanRegister.registerBean(beanClass);
            }
        }
    }

    @Override
    public int getOrder() {
        return Order.MAX;
    }

    /**
     * 初始化Bean后置处理器
     * @param beanMetadataCollection bean元数据集合
     */
    private void initializeBeanPostProcessor(Collection<BeanAnnotationScanMetadata> beanMetadataCollection) {
        beanMetadataCollection.stream()
                .filter(m -> Arrays.asList(BeanUtils.getDeclaredInterfaces(m.getType())).contains(BeanPostProcessor.class))
                .filter(m -> !beanRegister.containBean(m.getType()))
                .forEach(m -> beanRegister.registerBean(m.getType()));
    }
}
